package com.talkweb.newproject.admin.shiro;

import com.talkweb.newproject.admin.rest.SysResourceRest;
import com.talkweb.newproject.admin.rest.SysRoleRest;
import com.talkweb.newproject.admin.rest.SysUserRest;

import com.talkweb.newproject.api.model.common.ResponseResult;
import com.talkweb.newproject.api.model.common.Status;
import com.talkweb.newproject.api.model.shiro.*;
import com.talkweb.newproject.common.utils.DateUtil;
import com.talkweb.newproject.common.utils.ListUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by qsf on 2019/4/18.
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {
    @Autowired
    SysUserRest sysUserServiceFeign;
    @Autowired
    SysRoleRest sysRoleServiceFeign;
    @Autowired
    SysResourceRest sysResourceServiceFeign;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        UserInfo userInfo = (UserInfo) principals.getPrimaryPrincipal();

        try{
            Set<String> roleCodeList= this.getRoleCodesByUserId(userInfo.getUserId());
            if(!ListUtil.isEmpty(roleCodeList)) {
                authorizationInfo.addRoles(roleCodeList);
            }

            Set<String> permissionList = this.getPermissionByUserId(userInfo.getUserId());
            if(!ListUtil.isEmpty(permissionList)){
                authorizationInfo.addStringPermissions(permissionList);
            }
        }catch(Exception e) {
            log.error("get permisison error");
        }

        return authorizationInfo;
    }



    /**
     * 验证用户名密码是否正确
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String loginName = (String) token.getPrincipal();
        UserInfoParam userInfoParam = new UserInfoParam();
        userInfoParam.setLoginName(loginName);
        ResponseResult<UserInfo> responseResult = new ResponseResult();
        try {
            responseResult=sysUserServiceFeign.getUserInfoByLoginName(userInfoParam);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(ResponseResult.isSuccess(responseResult)) {
            UserInfo userInfo = responseResult.getData();
            if(userInfo==null) {
                return null;
            }
            userInfo.setLoginTime(DateUtil.getDateNow());
            String password = userInfo.getPassword();

            this.setSession("userInfo",userInfo);
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo,password,getName());
            return authenticationInfo;
        }else {
            log.error(responseResult.getMessage());
            throw new AuthorizationException(responseResult.getMessage());
        }
    }

    private void setSession(Object key, Object value) {
        Subject currentUser = SecurityUtils.getSubject();
        if(currentUser!= null) {
            Session session = currentUser.getSession();
            if(session!=null) {
                session.setAttribute(key,value);
            }
        }
    }

    /**
     * 根据userid获取roleCode集合
     * @param userId
     * @return
     */
    private Set<String> getRoleCodesByUserId(Long userId) throws Exception {
        Set<String> result = new HashSet<>();
        SysRoleParam sysRoleParam = new SysRoleParam();
        sysRoleParam.setUserId(userId);

        ResponseResult<SysRole> sysRoleResponseResult = sysRoleServiceFeign.getSysRoleByUserId(sysRoleParam);

        if(sysRoleResponseResult.getStatus().getValue().equals(Status.FAILD.getValue())) {
            List<SysRole> dataList = sysRoleResponseResult.getDataList();
            if(!ListUtil.isEmpty(dataList)) {
                for(SysRole sysRole: dataList) {
                    result.add(sysRole.getRoleCode());
                }
            }
        }else {
            log.error("getSysRoleByUserId error");
            return null;
        }

        return result;
    }

    /**
     * 根据userid获取permission集合
     * @param userId
     * @return
     */
    private Set<String> getPermissionByUserId(Long userId) throws Exception {
        Set<String> result = new HashSet<>();
        RolePermissionParam rolePermissionParam = new RolePermissionParam();
        rolePermissionParam.setUserId(userId);
        ResponseResult<RolePermission> responseResult = sysResourceServiceFeign.selectShiroUrlPermissionByUserId(rolePermissionParam);

        if(responseResult.getStatus().getValue().equals(Status.SUCCESS.getValue())) {
            List<RolePermission> dataList = responseResult.getDataList();
            if(!ListUtil.isEmpty(dataList)) {
                for(RolePermission rolePermission: dataList) {
                    result.add(rolePermission.getPermission());
                }
            }
        }else {
            log.error("getPermissionByUserId error");
            return null;
        }

        return result;
    }

}
